package linked_list

import (
	"bytes"
	"fmt"
)

type LinkedList struct {
	dummyHead *Node
	size      int
}

type Node struct {
	// 值
	val interface{}
	// 指向下一个node
	next *Node
}

func Constructor() *LinkedList {
	return &LinkedList{
		dummyHead: &Node{},
	}
}

func (l *LinkedList) Empty() bool {
	return l.size == 0
}

func (l *LinkedList) Size() int {
	return l.size
}

func (l *LinkedList) Get(index int) interface{} {
	if index < 0 || index > l.size {
		panic("Index is illegal")
	}

	cur := l.dummyHead.next
	for i := 0; i < index; i++ {
		cur = cur.next
	}
	return cur.val
}

func (l *LinkedList) Add(index int, e interface{}) {

	if index < 0 || index > l.size {
		panic("Index is illegal")
	}

	prev := l.dummyHead

	for i := 0; i < index; i++ {
		prev = prev.next
	}

	prev.next = &Node{e, prev.next}
	l.size++
}

// 在链表头添加新的元素
func (l *LinkedList) AddFirst(e interface{}) {
	l.Add(0, e)
}

// 在链表末尾添加新的元素
func (l *LinkedList) AddLast(e interface{}) {
	l.Add(l.size, e)
}

func (l *LinkedList) String() string {
	buffer := bytes.Buffer{}
	cur := l.dummyHead.next
	for cur != nil {
		buffer.WriteString(fmt.Sprint(cur.val) + "->")
		cur = cur.next
	}
	buffer.WriteString("nil")

	return buffer.String()
}
